/**
 * @author 老刘
 * @desc 加入购物车
 */
const app = getApp();
Page({
	data: {
		imgUrl: '', // 动画图片
		hideCount: true, // 是否隐藏购物车上的数字
		count: 0, // 购物车上的计数
		isHideCartIcon: true // 是否隐藏物品小图标
	},

	onLoad () {
		const systemInfo = app.globalData.systemInfo;
		let cartPos = {};
		// 购物车 x y 坐标
		cartPos['x'] = systemInfo.windowWidth * 0.8;
		cartPos['y'] = systemInfo.windowHeight * 0.8;
		this.setData({
			cartPos: cartPos
		});
	},
	/**
	 * 商品的点击事件
	 * @method handleGood
	 * @param {object} e 事件
	 */
	handleGood (e) {
		const imgUrl = e.currentTarget.dataset.url;
		this.setData({imgUrl});
		// 如果good_box正在运动，则不处理
		if (!this.data.isHideCartIcon) return;
		// 定义手指点击位置
		let finger = {};
		// 定义动画顶点位置
		let topPoint = {};
		finger['x'] = e.touches[0].clientX;
		finger['y'] = e.touches[0].clientY;
		// 当手指点击位置y轴小于购物车位置时，顶点以手指点击位置向上移150
		if (finger['y'] < this.data.cartPos['y']) {
			topPoint['y'] = finger['y'] - 150;
		} else {
			// 当手指点击位置y轴大于购物车位置时，顶点以购物车位置向上移150
			topPoint['y'] = this.data.cartPos['y'] - 150;
		}
		// 点击位置是否在购物车右面
		let isRight = false;
		if (finger['x'] > this.data.cartPos['x']) {
			// 点击位置在购物车右面时，顶点y轴应该在购物车下方
			isRight = true;
			topPoint['y'] = finger['y'] - Math.abs(this.data.cartPos['y'] - finger['y']);
			// 点击位置在购物车右面时，顶点x轴应该点击位置左侧
			topPoint['x'] = Math.abs(finger['x'] - this.data.cartPos['x']) / 2 - finger['x'];
		} else {
			// 点击位置在购物车左侧时，顶点x轴应该点击位置右侧
			topPoint['x'] = Math.abs(finger['x'] - this.data.cartPos['x']) / 2 + finger['x'];
		}

		// 计算出贝塞尔曲线运动位置数组
		let linePos = this.bezier([finger, topPoint, this.data.cartPos], 30, isRight);
		this.setData({
			linePos: linePos,
			finger: finger
		});
		// 开始动画
		this.startAnimation(linePos);
	},

	/**
	 * 开始动画
	 * @method startAnimation
	 */
	startAnimation () {
		let index = 0; // 定义定时器执行次数
		let that = this;
		let bezierPoints = that.data.linePos['bezierPoints'];

		this.setData({
			isHideCartIcon: false,
			animateX: this.data.finger['x'],
			animateY: this.data.finger['y']
		});
		// 开启定时器，依次按照贝塞尔曲线位置做动画位移
		// setTimeout 替换 setInterval 避免出现时间差
		const timer = setTimeout(function f () {
			index++; // 记录定时器执行次数
			if (index < 30) {
				that.setData({ // 改变运动中图标位置
					animateX: bezierPoints[index]['x'],
					animateY: bezierPoints[index]['y']
				});
			}

			if (index >= 28) {
				/** 定时器执行达到28次则关闭定时器 */
				clearTimeout(timer);
				that.setData({
					isHideCartIcon: true,
					hideCount: false,
					count: that.data.count += 1
				});
				return;
			}
			setTimeout(f, 33);
		}, 33);
	},
	bezier (points, times, isRight) {
		// 0、以3个控制点为例，点A,B,C,AB上设置点D,BC上设置点E,DE连线上设置点F,则最终的贝塞尔曲线是点F的坐标轨迹。
		// 1、计算相邻控制点间距。
		// 2、根据完成时间,计算每次执行时D在AB方向上移动的距离，E在BC方向上移动的距离。
		// 3、时间每递增100ms，则D,E在指定方向上发生位移, F在DE上的位移则可通过AD/AB = DF/DE得出。
		// 4、根据DE的正余弦值和DE的值计算出F的坐标。
		// 邻控制AB点间距
		let bezierPoints = [];
		let pointsD = [];
		let pointsE = [];
		const DIST_AB = Math.sqrt(Math.pow(points[1]['x'] - points[0]['x'], 2) + Math.pow(points[1]['y'] - points[0]['y'], 2));
		// 邻控制BC点间距
		const DIST_BC = Math.sqrt(Math.pow(points[2]['x'] - points[1]['x'], 2) + Math.pow(points[2]['y'] - points[1]['y'], 2));
		// D每次在AB方向上移动的距离
		const EACH_MOVE_AD = DIST_AB / times;
		// E每次在BC方向上移动的距离
		const EACH_MOVE_BE = DIST_BC / times;
		// 点AB的正切
		const TAN_AB = (points[1]['y'] - points[0]['y']) / (points[1]['x'] - points[0]['x']);
		// 点BC的正切
		const TAN_BC = (points[2]['y'] - points[1]['y']) / (points[2]['x'] - points[1]['x']);
		// 点AB的弧度值
		const RADIUS_AB = Math.atan(TAN_AB);
		// 点BC的弧度值
		const RADIUS_BC = Math.atan(TAN_BC);
		// 每次执行
		for (let i = 1; i <= times; i++) {
			// AD的距离
			let distAD = EACH_MOVE_AD * i;
			// BE的距离
			let distBE = EACH_MOVE_BE * i;
			// D点的坐标
			let pointD = {};
			if (isRight) {
				pointD['x'] = -distAD * Math.cos(RADIUS_AB) + points[0]['x'];
			} else {
				pointD['x'] = distAD * Math.cos(RADIUS_AB) + points[0]['x'];
			}
			pointD['y'] = distAD * Math.sin(RADIUS_AB) + points[0]['y'];
			pointsD.push(pointD);
			// E点的坐标
			let pointE = {};
			if (isRight) {
				pointE['x'] = -distBE * Math.cos(RADIUS_BC) + points[1]['x'];
			} else {
				pointE['x'] = distBE * Math.cos(RADIUS_BC) + points[1]['x'];
			}

			pointE['y'] = distBE * Math.sin(RADIUS_BC) + points[1]['y'];
			pointsE.push(pointE);
			// 此时线段DE的正切值
			let tanDE = (pointE['y'] - pointD['y']) / (pointE['x'] - pointD['x']);
			// tanDE的弧度值
			let radiusDE = Math.atan(tanDE);
			// 地市DE的间距
			let distDE = Math.sqrt(Math.pow((pointE['x'] - pointD['x']), 2) + Math.pow((pointE['y'] - pointD['y']), 2));
			// 此时DF的距离
			let distDF = (distAD / DIST_AB) * distDE;
			// 此时DF点的坐标
			let pointF = {};
			pointF['x'] = distDF * Math.cos(radiusDE) + pointD['x'];
			pointF['y'] = distDF * Math.sin(radiusDE) + pointD['y'];
			bezierPoints.push(pointF);
		}
		return {
			'bezierPoints': bezierPoints
		};
	}
});
